<?php
/**
 * Abstract class for plugins type of <i>Psa_Plugin_Controller</i>.
 * 
 * LICENSE:
 * 
 * This library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with This library. If not, see <{@link http://www.gnu.org/licenses/}>.
 *
 * @link http://code.google.com/p/phpstartapp/
 * @author Bojan Mauser <bmauser@gmail.com>
 * @copyright Bojan Mauser 2009
 * @package psa
 * @subpackage plugins
 * @version $Id: Psa_Plugin_Controller.class.php 464 2009-03-24 00:30:12Z bmauser $
 */


/**
 * Abstract class for plugins type of <i>Psa_Plugin_Controller</i>.
 * Controller plugins are called by the {@link Psa_Plugin_Router Router} plugin. Controller plugins are used to decide which
 * model and view plugins to call so model and view plugins have to be called from the controler.
 * That decision can be made from given URL path if your web server is set to use rewrite rules,
 * which is common practice, but can also be made from get or post values. It's up to you what you will use.
 * 
 * There can be more controllers in your application. For example, you can have one for web, one for JSON
 * inteface, and one for SOAP interface. And they all calls the same model plugins but view plugnis will be different.
 * You can also write only one controller plugin which handles that all. 
 * 
 * You can write <i>Psa_Plugin_Controller</i> plugins by extending this class. Here is an example:
 * 
 * <code>
 * <?php
 * class my_plugin extends Psa_Plugin_Controller{
 * 	
 * 	// you have to define psa_main($params) method in your child class
 * 	function psa_main(){
 * 		
 * 		
 * 	}
 * }
 * ?>
 * </code>
 * 
 * @see Psa_Plugin_Router
 * @see Psa_Plugin_Model
 * @see Psa_Plugin_View
 */
abstract class Psa_Plugin_Controller{
	
	/**
	 * Reference to {@link Psa_Smarty} object
	 * @see smarty_use()
	 * @var Psa_Smarty
	 */
	protected $psa_smarty;
	
	
	/**
	 * Reference to {@link Psa_Dully} object
	 * @see dully_use()
	 * @var Psa_Dully
	 */
	protected $psa_dully;
	
	
	/**
	 * Instances new {@link Psa_Smarty} object and puts reference it in {@link Psa_Registry} object.
	 * New Smarty object object will be accessible by view plugins.
	 * You dont'n need to call this method explicitly, it will be called by {@link smarty_assign_result()}
	 * and {@link smarty_assign()} methods.
	 * @return object $Psa_Smary object of {@link Psa_Smarty} class
	 * @see smarty_assign_result()
	 * @see smarty_assign()
	 * @see Psa_Smarty.class.php
	 */
	public function smarty_use(){
		
		global $PSA_CFG;
		
		// include smarty class file
		include_once $PSA_CFG['folders']['basedir'] . '/scripts/Psa_Smarty.class.php';
		
		// make new smarty object and assign reference to registry
		Psa_Registry::get_instance()->psa_smarty = $this->psa_smarty = new Psa_Smarty();
		
		return $this->psa_smarty;
	}
	

	/**
	 * Instances new {@link Psa_Dully} object and puts reference it in {@link Psa_Registry} object.
	 * New Psa_Dully object object will be accessible by view plugins.
	 * You dont'n need to call this method explicitly, it will be called by {@link dully_assign_result()} and
	 * {@link dully_assign()} methods.
	 * @return object $psa_dully object of {@link Psa_Dully} class
	 * @see dully_assign_result()
	 * @see dully_assign()
	 * @see Psa_Dully.class.php
	 */
	public function dully_use(){
		
		global $PSA_CFG;
		
		// include smarty class file
		include_once $PSA_CFG['folders']['basedir'] . '/scripts/Psa_Dully.class.php';
		
		Psa_Registry::get_instance()->psa_dully = $this->psa_dully = new Psa_Dully;
		
		// folder with templates
		$this->psa_dully->template_dir = $PSA_CFG['folders']['dully']['template_dir'];
		
		// return reference
		return $this->psa_dully;
	}


	/**
	 * Wrapper method for {@link smarty_assign_object_properties()} method with {@link Psa_Result} object as argument.
	 * @see smarty_assign_object_properties()
	 */
	public function smarty_assign_result(){
		
		$this->smarty_assign_object_properties($psa_result = Psa_Result::get_instance());
	}
	
	
	/**
	 * Calls Smarty's assign() method for every property in <i>$object</i> object.
	 * Also calls {@link smarty_use()} method if not called before which instances new {@link Psa_Smarty} object.
	 * @param object $object
	 * @see smarty_use()
	 */
	public function smarty_assign_object_properties($object){
		
		// call smarty_use() method to instance new Smarty object if not already instanced
		if(!$this->psa_smarty instanceof Smarty)
			$this->smarty_use();
			
		// iterate through $psa_result object
		foreach($object as $key => &$value){
			$this->psa_smarty->assign($key,$value);
		}
	}
	
	
	/**
	 * Calls Smarty's assign() method.
	 * Also calls {@link smarty_use()} method if not called before which instances new {@link Psa_Smarty} object.
	 * @param string $varname
	 * @param mixed $var
	 * @see smarty_use()
	 * @see http://smarty.net/manual/en/api.assign.php
	 */
	public function smarty_assign($varname, $var){
		
		// call smarty_use() method to instance new Smarty object if not already instanced
		if(!$this->psa_smarty instanceof Smarty)
			$this->smarty_use();
			
		$this->psa_smarty->assign($varname, $var);
	}

	
	/**
	 * Wrapper method for {@link dully_assign_object_properties()} method with {@link Psa_Result} object as argument.
	 * @see dully_assign_object_properties()
	 */
	public function dully_assign_result(){
		
		$this->dully_assign_object_properties(Psa_Result::get_instance());
	}
	
	
	/**
	 * Calls Psa_Dully's {@link assign() Psa_Dully::assign()} method for every property in <i>$object</i> object.
	 * Also calls {@link dully_use()} method if not called before which instances new {@link Psa_Dully} object.
	 * @see dully_use()
	 */
	public function dully_assign_object_properties($object){
		
		// call dully_use() method to instance new Dully object if not already instanced
		if(!$this->psa_dully instanceof Psa_Dully)
			$this->dully_use();
		
		// iterate through $psa_result object
		foreach($object as $key => &$value){
			$this->psa_dully->assign($key,$value);
		}
	}
	
	
	/**
	 * Calls Psa_Dully's {@link assign() Psa_Dully::assign()} method.
	 * Also calls {@link dully_use()} method if not called before which instances new {@link Psa_Dully} object.
	 * @param string $varname
	 * @param mixed $var
	 * @see dully_use()
	 * @see Psa_Dully
	 * @see Psa_Dully::assign()
	 */
	public function dully_assign($varname, $var){
		
		// call dully_use() method to instance new Dully object if not already instanced
		if(!$this->psa_dully instanceof Psa_Dully)
			$this->dully_use();
		
		$this->psa_dully->assign($varname, $var);
	}
	
	
	/**
	 * Method that must be defined by the child class.
	 * It is supposed to add controller main functionality in this method.
	 * @param mixed $params can be anything you want to pass from Router plugin 
	 */	
	abstract protected function psa_main($params);
}

